/*
  This example program provides a trivial server program that listens for TCP
  connections on port 9995.  When they arrive, it writes a short message to
  each client connection, and closes each connection once it is flushed.

  Where possible, it exits cleanly in response to a SIGINT (ctrl-c).
*/


#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <signal.h>
#ifndef _WIN32
#include <netinet/in.h>
# ifdef _XOPEN_SOURCE_EXTENDED
#  include <arpa/inet.h>
# endif
#include <sys/socket.h>
#endif

#include <event2/bufferevent.h>
#include <event2/buffer.h>
#include <event2/listener.h>
#include <event2/util.h>
#include <event2/event.h>
#include <stddef.h>
#include <vector>
#include <map>
#include <algorithm>
#include <unistd.h>
#include <string>
#include <iostream>
#include <fstream>
#include "File.h"
#include "sqlite3test.cpp"

#define READBUFFER_MAX 4096

using namespace std;

static map<bufferevent*, string > users;
static map<string,bool> allusers;
static char piIp[30];
struct client {
    /* The clients socket. */
    int fd;
    /* The bufferedevent for this client. */
    struct bufferevent *buf_ev;
    struct evbuffer *buf;
    char mail[30];
};

Sqlite m_sqlite;
struct sqldata
{
    sqldata(){
        memset(user_mail,0,sizeof(user_mail));
        memset(user_name,0,sizeof(user_name));
        memset(user_pwd,0,sizeof(user_pwd));
    }
    char user_mail[30];
    char user_name[30];
    char user_pwd[30];
};

class map_value_finder
{
public:
    map_value_finder(const std::string &cmp_string):m_s_cmp_string(cmp_string){}
    bool operator ()(const std::map<bufferevent*, std::string>::value_type &pair)
    {
        return pair.second == m_s_cmp_string;
    }
private:
    const std::string &m_s_cmp_string;
};

class Server{

public:

    Server(int port=12301){
        PORT = port;
        m_sqlite.init_sqlite();

        char msg[1024];
        memset(msg,0,sizeof(msg));
        sprintf(msg,"SELECT * FROM user;");

        int result;
        char * errmsg = NULL;
        char **dbResult; //是 char ** 类型，两个*号
        int nRow, nColumn;
        int index;
        //        string temp;
        result = m_sqlite.sqlite_read_data(msg,&dbResult, &nRow, &nColumn, &errmsg);

        if(result!=SQLITE_OK){
            sprintf(msg,"sqlerror:%s",errmsg);
            printf("sqlerror:%s\n",errmsg);
        }
        else{
            if(nRow==0){
                printf("sqlerror:未查询到基础用户数据\n");
            }
            else{
                printf( "查到%d条用户数据\n", nRow );
                index = nColumn;
                memset(msg,0,sizeof(msg));
                for(int i = 0; i < nRow ; i++ )
                {
                    for( int j = 0 ; j < nColumn; j++ )
                    {
                        if(strcasecmp(dbResult[j],"user_mail")==0){
                            allusers[dbResult[index]]=false;
                            //                            printf("%s\n",dbResult[index]);
                        }
                        ++index;
                    }
                }
            }
        }
        sqlite3_free_table(dbResult);
        sqlite3_free(errmsg);
    }

    static void listener_cb(struct evconnlistener *listener, evutil_socket_t fd,
                            struct sockaddr *sa, int socklen, void *user_data){
        struct event_base *base = (event_base *)user_data;
        struct bufferevent *bev;
//        struct evbuffer *buf = evbuffer_new();
        struct client *client;

        bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);
        if (!bev) {
            fprintf(stderr, "Error constructing bufferevent!");
            event_base_loopbreak(base);
            return;
        }
        client = (struct client *)calloc(1,sizeof (*client));

        if(client==NULL){
            printf("malloc failed");
            return;
        }
        client->fd = fd;
        client->buf = evbuffer_new();
        client->buf_ev = bev;
        bufferevent_setcb(bev, conn_readcb, conn_writecb, conn_eventcb, client);
        bufferevent_enable(bev, EV_WRITE|EV_READ|EV_PERSIST);
        bufferevent_setwatermark(bev,EV_READ,0,0);

        //        static const char MESSAGE[] = "Hello, World!\n";
        //        bufferevent_write(bev, MESSAGE, strlen(MESSAGE));
    }

    static int sqllite_callback(void *data, int argc, char **argv, char **azColName){
        printf("sqllite_callback:%d\n",argc);
        for(int i=0; i<argc; i++){
            printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");

            if(strcasecmp(azColName[i],"USER_PWD")==0){
                printf("success!\n");
                //                                if(strcmp(argv[i],static_cast<struct tempdata*>(data)->pwd)==0){
                //                                    static const char MESSAGE[] = "success";
                //                                    socksend(static_cast<struct bufferevent *>(static_cast<struct tempdata*>(data)->data),MESSAGE,1);
                //                                }
                //                                else{
                //                                    static const char MESSAGE[] = "wrong password,please check.";
                //                                    socksend(static_cast<struct bufferevent *>(static_cast<struct tempdata*>(data)->data),MESSAGE,1);
                //                                }
            }
            else{
                printf("fail!\n");
            }
        }
        static const char MESSAGE[] = "wrong password,please check.";
        socksend(static_cast<struct bufferevent *>(data),MESSAGE,1);
        //memcpy(getData.user_mail,
        return 0;
    }

    static void conn_readcb(struct bufferevent *bev, void *user_data){
        //struct evbuffer *input = bufferevent_get_input(bev);
        char msg[READBUFFER_MAX];
        //        struct evbuffer *buf = (struct evbuffer *)user_data;
        struct client *buf = (struct client *)user_data;
        size_t len = bufferevent_read(bev,msg,sizeof(msg)-1);

        evbuffer_add(buf->buf,msg,len);
        //        const char *x = '\n';
        //        struct evbuffer_ptr ptr = evbuffer_search(buf,x,1,0);
        //        char *rline = evbuffer_readln(buf,&len,EVBUFFER_EOL_LF);
        char *rline = evbuffer_readln(buf->buf,&len,EVBUFFER_EOL_LF);
        if(rline!=NULL){
            memcpy(msg,rline,len);
            //len = evbuffer_remove(buf,msg,len);

            if(msg[0]=='@'&&msg[1]=='@'){

            }
            else{
                static const char MESSAGE[] = "error start";
                socksend(bev,MESSAGE,100);
                bufferevent_free(bev);
                return;
            }

        }
        else{
            //            bufferevent_free(bev);
            return;
        }

        free(rline);

        int len_r,i;

        int rev_len=0;
        char rev_data[READBUFFER_MAX]={0};

        struct sockaddr_storage ss;
        ev_socklen_t socklen = sizeof(ss);
        int got_port = -1;
        void *inaddr;
        char addrbuf[128];
        const char *addr;
        bool addrok = true;
        string ipvalue,recvvalue;

        char user_mail[30];
        char user_pwd[30];
        char user_name[30];
        char user_img[30];
        //        char *zErrMsg = 0;

        memset(&ss,0,sizeof(ss));
        memset(addrbuf,0,sizeof(addrbuf));
        if(getpeername(bufferevent_getfd(bev),(struct sockaddr *)&ss,&socklen)){
            perror("getsockname() failed");
            addrok = false;
            goto cc1;
        }

        if (ss.ss_family == AF_INET) {
            got_port = ntohs(((struct sockaddr_in*)&ss)->sin_port);
            inaddr = &((struct sockaddr_in*)&ss)->sin_addr;
        } else if (ss.ss_family == AF_INET6) {
            got_port = ntohs(((struct sockaddr_in6*)&ss)->sin6_port);
            inaddr = &((struct sockaddr_in6*)&ss)->sin6_addr;
        }
        else {
            fprintf(stderr, "Weird address family %d\n",
                    ss.ss_family);
            addrok = false;
            goto cc1;
        }

        addr = evutil_inet_ntop(ss.ss_family, inaddr, addrbuf,
                                sizeof(addrbuf));
        if (addr) {
            //printf("get data on->%s:%d\n", addr, got_port);
        } else {
            fprintf(stderr, "evutil_inet_ntop failed\n");
            addrok = false;
        }
cc1:
        //memset(addrbuf,0,sizeof(addrbuf));
        if(addrok){
            //printf("get data on->%s:%d\n", addrbuf, got_port);
        }
        else{
            strcpy(addrbuf,"0.0.0.0");
            addr = addrbuf;
        }
        //sprintf(addrbuf,"%s",addr);
        ipvalue = addrbuf;

        msg[len] = '\0';
        memcpy(rev_data,msg,len);
        rev_len=len;

        if(rev_len>9){
            len_r = (rev_data[2]-'0')*1000+(rev_data[3]-'0')*100+(rev_data[4]-'0')*10+(rev_data[5]-'0');
            memset(msg,0,sizeof(msg));
            memset(msg,'@',6);

            strncpy(&msg[6],&rev_data[6],len_r-6);
            sprintf(&msg[len_r],"|%s\n",addrbuf);
            //printf("%s\n",msg);
            sprintf(&msg[2],"%04d",(int)strlen(msg)-1);
            //printf("%s\n",msg);
            msg[6] = rev_data[6];
            recvvalue = msg;

            if(len_r==rev_len){
                i = (rev_data[6]-'0')*1000+(rev_data[7]-'0')*100+(rev_data[8]-'0')*10+(rev_data[9]-'0');
                if(i==0){//心跳包
                    time_t timep;
                    struct tm *p;
                    time(&timep);
                    p = gmtime(&timep);
                    sprintf(rev_data,"%d-%02d-%02dT%02d:%02d:%02d",(1900+p->tm_year),(1+p->tm_mon),p->tm_mday,p->tm_hour+8,p->tm_min,p->tm_sec);
                    socksend(bev,rev_data,0);
                }
                else if(i==1){//用户登录
                    i = 10;
                    memset(user_mail,0,sizeof(user_mail));
                    memset(user_pwd,0,sizeof(user_pwd));

                    while (rev_data[i]) {
                        if(rev_data[i]=='|'){
                            break;
                        }
                        i++;
                    }
                    memcpy(user_mail,&rev_data[10],i-10);
                    memcpy(user_pwd,&rev_data[i+1],rev_len-i-1);
                    //                    printf("user_mail:%s\n%s\n",user_mail,user_pwd);

                    memset(msg,0,sizeof(msg));
                    std::map<bufferevent*, std::string>::iterator it = users.end();
                    it = std::find_if(users.begin(), users.end(), map_value_finder(user_mail));
                    if (it == users.end()){
                        //                        printf("not found:%s\n",user_mail);
                    }else{
                        //                        printf("found key:%d value:%s\n", it->first, it->second.c_str());
                        //                        memset(msg,0,sizeof(msg));
                        //                        strncpy(msg,&rev_data[6],len_r-6);
                        sprintf(msg,"用户已经在其它设备登陆!");
                        socksend(bev,msg,1);
                        return;
                    }

                    sprintf(msg,"SELECT * FROM user WHERE user_mail='%s';",user_mail);
                    //len_r = m_sqlite.sqlite_read(msg,sqllite_callback,bev,&zErrMsg);
                    int result;
                    char * errmsg = NULL;
                    char **dbResult; //是 char ** 类型，两个*号
                    int nRow, nColumn;
                    int index;

                    result = m_sqlite.sqlite_read_data(msg,&dbResult, &nRow, &nColumn, &errmsg);
                    memset(rev_data,0,sizeof(rev_data));

                    if(result!=SQLITE_OK){
                        sprintf(rev_data,"sqlerror:%s",errmsg);
                        socksend(bev,rev_data,1);
                        sqlite3_free_table(dbResult);
                        sqlite3_free(errmsg);
                    }
                    else{
                        if(nRow==0){
                            sprintf(rev_data,"sqlerror:未查询到用户数据，请联系管理员进行注册！");
                        }
                        else{
                            index = nColumn;
                            memset(msg,0,sizeof(msg));
                            //                            printf( "查到%d条记录\n", nRow );
                            for( i = 0; i < nRow ; i++ )
                            {
                                //                                printf( "第 %d 条记录\n", i+1 );
                                for( int j = 0 ; j < nColumn; j++ )
                                {
                                    //                                    printf( "字段名:%s ß> 字段值:%s\n", dbResult[j], dbResult [index] );
                                    if(strcasecmp(dbResult[j],"user_pwd")==0){
                                        if(strcasecmp(dbResult[index],user_pwd)==0){
                                            sprintf(rev_data,"success");
                                        }
                                        else{
                                            sprintf(rev_data,"wrong password,please check.");
                                        }
                                    }
                                    ++index;
                                }
                                sprintf(msg,"%s:%s|%s:%s|%s:%s|%s:%s|%s:%s",dbResult[0],dbResult[nColumn],dbResult[1],dbResult[nColumn+1],dbResult[2],dbResult[nColumn+2],dbResult[3],dbResult[nColumn+3],dbResult[4],dbResult[nColumn+4]);
                            }
                        }

                        sqlite3_free_table(dbResult);
                        sqlite3_free(errmsg);

                        if(strcasecmp(rev_data,"success")==0){
                            users[bev] = user_mail;
                            allusers[user_mail] = true;
                            sprintf(buf->mail,"%s",user_mail);
                            char ssData[1024]={0};
                            sprintf(ssData,"success|%s",msg);
                            socksend(bev,ssData,1);
                            map<bufferevent*, string >::iterator map_iter = users.begin();
                            for(;map_iter!=users.end();map_iter++){
                                if(map_iter->first!=bev)
                                    socksend(map_iter->first,msg,1000);
                                //                            bufferevent_write(map_iter->first, msg, strlen(msg));
                            }
                            //                              typedef std::multimap<string,string>::iterator multimap_iterator; // 为了方便使用，typedef一下迭代器定义
                            //                              std::pair<multimap_iterator,multimap_iterator> it =
                            //                                  offlineMessages.equal_range(user_mail);
                            //                              while(it.first!=it.second){ //查找
                            //                                  socksend(bev,it.first->second,2001);
                            //                                  offlineMessages.erase(it.first);
                            //                              }
                            memset(msg,0,sizeof(msg));
                            sprintf(msg,"SELECT * FROM temp WHERE mail='%s';",user_mail);
                            //len_r = m_sqlite.sqlite_read(msg,sqllite_callback,bev,&zErrMsg);
                            int result1;
                            char * errmsg1 = NULL;
                            char **dbResult1; //是 char ** 类型，两个*号
                            int nRow1, nColumn1;
                            int index1;

                            result1 = m_sqlite.sqlite_read_data(msg,&dbResult1, &nRow1, &nColumn1, &errmsg1);
                            //                              memset(rev_data,0,sizeof(rev_data));

                            if(result1!=SQLITE_OK){
                                printf("sqlerror:%s",errmsg1);
                            }
                            else{
                                if(nRow1==0){
                                    //sprintf(rev_data,"sqlerror:未查询到用户数据，请联系管理员进行注册！");
                                }
                                else{
                                    char type[10];
                                    index1 = nColumn1;
                                    memset(msg,0,sizeof(msg));
                                    for( i = 0; i < nRow1 ; i++ )
                                    {
                                        for( int j = 0 ; j < nColumn1; j++ )
                                        {
                                            if(strcasecmp(dbResult1[j],"type")==0){
                                                strcpy(type,dbResult1[index1]);
                                            }
                                            if(strcasecmp(dbResult1[j],"message")==0){
                                                socksend(bev,dbResult1[index1],(type[0]-'0')*1000+(type[1]-'0')*100+(type[2]-'0')*10+(type[3]-'0'));//2001
                                            }
                                            ++index1;
                                        }
                                    }
                                    sprintf(msg,"DELETE FROM temp WHERE mail='%s';",
                                            user_mail);
                                    m_sqlite.sqlite_write(msg,0);
                                }
                            }

                            sqlite3_free_table(dbResult1);
                            sqlite3_free(errmsg1);

                        }
                        else{
                            socksend(bev,rev_data,1);
                        }
                    }

                }
                else if(i==1001){//answer one line
                    i = 10;
                    memset(user_mail,0,sizeof(user_mail));
                    while (rev_data[i]) {
                        if(rev_data[i]=='|'){
                            break;
                        }
                        i++;
                    }

                    memcpy(user_mail,&rev_data[10],i-10);

                    std::map<bufferevent*, std::string>::iterator it = users.end();
                    it = std::find_if(users.begin(), users.end(), map_value_finder(user_mail));
                    memset(msg,0,sizeof(msg));
                    if (it == users.end()){
                        printf("not found:%s\n",user_mail);
                        sprintf(msg,"not found:%s",user_mail);
                    }else{
                        //                        printf("found key:%d value:%s\n", it->first, it->second.c_str());
                        //                        memset(msg,0,sizeof(msg));
                        //                        strncpy(msg,&rev_data[6],len_r-6);
                        sprintf(msg,"success");
                        socksend(it->first,&rev_data[i+1],1001);
                    }
                    socksend(bev,msg,1001);
                }
                else if(i==2000||i==2010){//单独发送
                    int type = i;
                    i = 10;
                    memset(user_mail,0,sizeof(user_mail));
                    while (rev_data[i]) {
                        if(rev_data[i]=='|'){
                            break;
                        }
                        i++;
                    }

                    memcpy(user_mail,&rev_data[10],i-10);

                    time_t timep;
                    struct tm *p;
                    time(&timep);
                    p = gmtime(&timep);
                    char mtime[128];
                    memset(mtime,0,sizeof(mtime));
                    sprintf(mtime,"%d-%02d-%02dT%02d:%02d:%02d",(1900+p->tm_year),(1+p->tm_mon),p->tm_mday,p->tm_hour+8,p->tm_min,p->tm_sec);
                    //printf("%d-%d-%d %d:%d:%d",(1900+p->tm_year),(1+p->tm_mon),p->tm_mday,p->tm_hour+8,p->tm_min,p->tm_sec);
                    sprintf(&rev_data[len_r],"|%s",mtime);

                    std::map<bufferevent*, std::string>::iterator it = users.end();
                    it = std::find_if(users.begin(), users.end(), map_value_finder(user_mail));
                    //                    memset(msg,0,sizeof(msg));
                    if (it == users.end()){
                        map<string,bool>::iterator iter;
                        iter = allusers.find(user_mail);
                        if(iter==allusers.end()){
                            printf("not found:%s\n",user_mail);
                            sprintf(msg,"该用户不存在，或已删除:%s",user_mail);
                        }
                        else{
                            //                            offlineMessages.insert(make_pair(user_mail,&rev_data[10]));
                            char temp[10];
                            sprintf(temp,"%d",type+1);

                            sprintf(msg,"INSERT INTO temp(mail,type,message) VALUES('%s','%s','%s');",
                                    user_mail,temp,&rev_data[10]);
                            //len_r = m_sqlite.sqlite_read(msg,sqllite_callback,bev,&zErrMsg);
                            int result;
                            char * errmsg = NULL;

                            result = m_sqlite.sqlite_write(msg,&errmsg);

                            //                            memset(msg,0,sizeof(msg));
                            if(result!=SQLITE_OK){
                                printf("sqlerror:%s\n",errmsg);
                            }
                            else{

                            }
                            sqlite3_free(errmsg);

                            sprintf(msg,"success|%s|offline",mtime);
                        }
                    }else{
                        //                        printf("found key:%d value:%s\n", it->first, it->second.c_str());
                        //                        memset(msg,0,sizeof(msg));
                        //                        strncpy(msg,&rev_data[6],len_r-6);
                        sprintf(msg,"success|%s",mtime);
                        socksend(it->first,&rev_data[10],type+1);
                    }

                    socksend(bev,msg,type);
                }
                else if(i==2001||i==2020){//群发
                    int type = i;
                    i = 10;
                    time_t timep;
                    struct tm *p;
                    time(&timep);
                    p = gmtime(&timep);
                    char mtime[128];
                    memset(mtime,0,sizeof(mtime));
                    sprintf(mtime,"%d-%02d-%02dT%02d:%02d:%02d",(1900+p->tm_year),(1+p->tm_mon),p->tm_mday,p->tm_hour+8,p->tm_min,p->tm_sec);
                    //printf("%d-%d-%d %d:%d:%d",(1900+p->tm_year),(1+p->tm_mon),p->tm_mday,p->tm_hour+8,p->tm_min,p->tm_sec);
                    sprintf(&rev_data[len_r],"|%s",mtime);

                    map<bufferevent*, string >::iterator map_iter = users.begin();
                    for(;map_iter!=users.end();map_iter++){
                        if(map_iter->first!=bev){
                            if(type==2001)
                                socksend(map_iter->first,&rev_data[10],type);
                            else
                                socksend(map_iter->first,&rev_data[10],2011);
                        }
                    }

                    char * errmsg = NULL;
                    char temp[10];
                    m_sqlite.begin_transaction();

                    map<string,bool>::iterator iter = allusers.begin();
                    for(;iter!=allusers.end();iter++){
                        if(!iter->second){
                            if(type==2001)
                                sprintf(temp,"%d",type);
                            else
                                sprintf(temp,"%d",2011);
                            sprintf(msg,"INSERT INTO temp(mail,type,message) VALUES('%s','%s','%s');",
                                    iter->first.c_str(),temp,&rev_data[10]);
                            m_sqlite.sqlite_write(msg,&errmsg);
                            //                            offlineMessages.insert(make_pair(iter->first,&rev_data[10]));
                        }
                    }

                    m_sqlite.commit();
                    sqlite3_free(errmsg);

                    sprintf(msg,"success|%s",mtime);
                    if(type==2001)
                        socksend(bev,msg,2001);
                    else
                        socksend(bev,msg,2010);
                }
                else if(i==2100){//用户参数设置
                    memset(user_mail,0,sizeof(user_mail));
                    memset(user_pwd,0,sizeof(user_pwd));
                    memset(user_name,0,sizeof(user_name));
                    memset(user_img,0,sizeof(user_img));
                    memset(msg,0,sizeof(msg));
                    i=10;
                    while (rev_data[i]) {
                        if(rev_data[i]=='|'){
                            break;
                        }
                        i++;
                    }
                    int x = i+1;
                    while (rev_data[x]) {
                        if(rev_data[x]=='|'){
                            break;
                        }
                        x++;
                    }

                    memcpy(user_mail,&rev_data[20],i-20);
                    memcpy(user_name,&rev_data[i+11],x-i-11);
                    i=x+1;
                    while (rev_data[i]) {
                        if(rev_data[i]=='|'){
                            break;
                        }
                        i++;
                    }
                    memcpy(user_pwd,&rev_data[x+10],i-x-10);
                    memcpy(user_img,&rev_data[i+10],rev_len-i-10);

                    sprintf(msg,"UPDATE user SET user_name='%s',user_pwd='%s',user_img='%s' WHERE user_mail='%s';",
                            user_name,user_pwd,user_img,user_mail);
                    //len_r = m_sqlite.sqlite_read(msg,sqllite_callback,bev,&zErrMsg);
                    int result;
                    char * errmsg = NULL;

                    result = m_sqlite.sqlite_write(msg,&errmsg);
                    //memset(rev_data,0,sizeof(rev_data));

                    memset(msg,0,sizeof(msg));
                    if(result!=SQLITE_OK){
                        sprintf(msg,"sqlerror:%s",errmsg);
                        socksend(bev,msg,2100);
                    }
                    else{
                        map<bufferevent*, string >::iterator map_iter = users.begin();
                        for(;map_iter!=users.end();map_iter++){
                            if(map_iter->first!=bev)
                                socksend(map_iter->first,&rev_data[10],2101);
                            //                            bufferevent_write(map_iter->first, msg, strlen(msg));
                        }

                        sprintf(msg,"success");
                        socksend(bev,msg,2100);

                    }
                    sqlite3_free(errmsg);

                }
                else if(i==3000){//查询
                    i = 10;
                    while (rev_data[i]) {
                        if(rev_data[i]=='|'){
                            break;
                        }
                        i++;
                    }
                    memcpy(user_mail,&rev_data[10],i-10);
                    memcpy(user_pwd,&rev_data[i+1],rev_len-i-1);

                    sprintf(msg,"SELECT * FROM user WHERE %s='%s';",user_mail,user_pwd);
                    int result;
                    char * errmsg = NULL;
                    char **dbResult; //是 char ** 类型，两个*号
                    int nRow, nColumn;
                    int index;

                    result = m_sqlite.sqlite_read_data(msg,&dbResult, &nRow, &nColumn, &errmsg);
                    memset(rev_data,0,sizeof(rev_data));

                    if(result!=SQLITE_OK){
                        sprintf(rev_data,"sqlerror:%s",errmsg);
                    }
                    else{
                        if(nRow==0){
                            sprintf(rev_data,"sqlerror:未查询到相关数据:%s:%s",user_mail,user_pwd);
                        }
                        else{
                            index = nColumn;
                            string answer;
                            string title,value;
                            //                            printf( "查到%d条记录\n", nRow );
                            for( i = 0; i < nRow ; i++ )
                            {
                                //                                printf( "第 %d 条记录\n", i+1 );
                                for( int j = 0 ; j < nColumn; j++ )
                                {
                                    //                                    printf( "字段名:%s ß> 字段值:%s\n", dbResult[j], dbResult [index] );
                                    title = dbResult[j];
                                    value = dbResult[index];
                                    answer+=title+":"+value+"&";
                                    ++index;
                                }
                                answer+="|";
                            }
                            sprintf(msg,"success:%s",answer.c_str());
                        }

                    }
                    socksend(bev,rev_data,3000);
                    sqlite3_free_table(dbResult);
                    sqlite3_free(errmsg);
                }
                else if(i==3001){//插入
                    memset(user_mail,0,sizeof(user_mail));
                    memset(user_pwd,0,sizeof(user_pwd));
                    memset(user_name,0,sizeof(user_name));
                    memset(user_img,0,sizeof(user_img));
                    memset(msg,0,sizeof(msg));
                    i=10;
                    while (rev_data[i]) {
                        if(rev_data[i]=='|'){
                            break;
                        }
                        i++;
                    }
                    int x = i+1;
                    while (rev_data[x]) {
                        if(rev_data[x]=='|'){
                            break;
                        }
                        x++;
                    }

                    memcpy(user_mail,&rev_data[20],i-20);
                    memcpy(user_name,&rev_data[i+11],x-i-11);
                    i=x+1;
                    while (rev_data[i]) {
                        if(rev_data[i]=='|'){
                            break;
                        }
                        i++;
                    }
                    memcpy(user_pwd,&rev_data[x+10],i-x-10);
                    memcpy(user_img,&rev_data[i+10],rev_len-i-10);

                    sprintf(msg,"INSERT INTO user(user_mail,user_name,user_pwd,user_img) VALUES('%s','%s','%s','%s');",
                            user_mail,user_name,user_pwd,user_img);
                    //len_r = m_sqlite.sqlite_read(msg,sqllite_callback,bev,&zErrMsg);
                    int result;
                    char * errmsg = NULL;

                    result = m_sqlite.sqlite_write(msg,&errmsg);
                    //memset(rev_data,0,sizeof(rev_data));

                    memset(msg,0,sizeof(msg));
                    if(result!=SQLITE_OK){
                        sprintf(msg,"sqlerror:%s",errmsg);
                        socksend(bev,msg,3001);
                    }
                    else{
                        sprintf(msg,"success");
                        socksend(bev,msg,3001);
                        allusers[user_mail]=false;
                    }
                    sqlite3_free(errmsg);
                }
                else if(i==3002){//删除
                    i = 10;
                    while (rev_data[i]) {
                        if(rev_data[i]=='|'){
                            break;
                        }
                        i++;
                    }
                    memcpy(user_mail,&rev_data[10],i-10);
                    memcpy(user_pwd,&rev_data[i+1],rev_len-i-1);

                    sprintf(msg,"SELECT * FROM user WHERE user_mail='%s';",user_mail);
                    int result;
                    char * errmsg = NULL;
                    char **dbResult; //是 char ** 类型，两个*号
                    int nRow, nColumn;
                    int index;

                    result = m_sqlite.sqlite_read_data(msg,&dbResult, &nRow, &nColumn, &errmsg);

                    if(result!=SQLITE_OK){
                        sprintf(rev_data,"sqlerror:%s",errmsg);
                        sqlite3_free_table(dbResult);
                        sqlite3_free(errmsg);
                    }
                    else{
                        bool ascertain = false;
                        if(nRow==0){
                            sprintf(rev_data,"sqlerror:未查询到用户数据:%s",user_mail);
                        }
                        else{
                            index = nColumn;
                            for( i = 0; i < nRow ; i++ )
                            {
                                for( int j = 0 ; j < nColumn; j++ )
                                {
                                    //                                    printf( "字段名:%s ß> 字段值:%s\n", dbResult[j], dbResult [index] );
                                    if(strcasecmp(dbResult[j],"user_pwd")==0){
                                        if(strcasecmp(dbResult[index],user_pwd)==0){
                                            sprintf(rev_data,"success");
                                            ascertain = true;
                                        }
                                        else{
                                            sprintf(rev_data,"wrong password");
                                        }
                                    }
                                    ++index;
                                }
                            }

                        }

                        sqlite3_free_table(dbResult);
                        sqlite3_free(errmsg);

                        if(ascertain){
                            //删除user表数据
                            sprintf(msg,"DELETE FROM user WHERE user_mail='%s';",
                                    user_mail);
                            result = m_sqlite.sqlite_write(msg,&errmsg);
                            if(result!=SQLITE_OK){
                                ascertain = false;
                                sprintf(rev_data,"delete user sqlerror:%s",errmsg);
                            }
                            //删除temp表数据
                            sprintf(msg,"DELETE FROM temp WHERE mail='%s';",
                                    user_mail);
                            result = m_sqlite.sqlite_write(msg,&errmsg);
                            if(result!=SQLITE_OK){
                                sprintf(rev_data,"delete temp sqlerror:%s",errmsg);
                            }
                            //删除allusers数据
                            map<string,bool>::iterator iter;
                            iter = allusers.find(user_mail);
                            if(iter==allusers.end()){
                                printf("not find allusers:%s erase.\n",user_mail);
                                sprintf(rev_data,"not find allusers:%s erase.",user_mail);
                            }
                            else{
                                allusers.erase(iter);
                            }
                            //删除users数据
                            map<bufferevent*, std::string>::iterator it = users.end();
                            it = std::find_if(users.begin(), users.end(), map_value_finder(user_mail));
                            if (it == users.end()){
                                printf("users not found:%s\n",user_mail);
                                sprintf(rev_data,"users not found:%s",user_mail);
                            }else{
                                bufferevent_free(it->first);
                            }
                        }

                        if(ascertain){
                            sprintf(msg,"success:%s",rev_data);
                        }

                    }
                    socksend(bev,rev_data,3002);

                }
                else if(i==4000){//文件服务器链接
                    if(strcasecmp(piIp,addrbuf)==0){

                    }
                    else{
                        sprintf(piIp,"%s",addrbuf);
                        sprintf(rev_data,"success|%s",piIp);
                        socksend(bev,rev_data,4000);
                        sprintf(rev_data,"%s",piIp);
                        map<bufferevent*, string >::iterator map_iter = users.begin();
                        for(;map_iter!=users.end();map_iter++){
                            socksend(map_iter->first,rev_data,4001);
                        }
                    }
                }
                else if(i==4001){//获取文件服务器地址
                    sprintf(rev_data,"%s",piIp);
                    socksend(bev,rev_data,4001);
                }
            }
            else{
                static const char MESSAGE[] = "error rev_len";
                socksend(bev,MESSAGE,1);
                bufferevent_free(bev);
            }
        }
        else{
            static const char MESSAGE[] = "error rev_len<10";
            socksend(bev,MESSAGE,1);
            bufferevent_free(bev);
        }
    }

    static void conn_writecb(struct bufferevent *bev, void *user_data){
        struct evbuffer *output = bufferevent_get_output(bev);
        if (evbuffer_get_length(output) == 0) {
            //printf("flushed answer\n");
            //		bufferevent_free(bev);
        }
    }

    static void conn_eventcb(struct bufferevent *bev, short events, void *user_data){
        if (events & BEV_EVENT_TIMEOUT) {
            printf("Timed out.\n");
        }
        else if (events & BEV_EVENT_EOF) {
            printf("Connection closed.\n");
        } else if (events & BEV_EVENT_ERROR) {
            printf("Got an error on the connection: %s\n",
                   strerror(errno));/*XXX win32*/
        }
        /* None of the other events can happen here, since we haven't enabled
             * timeouts */

        //        std::vector<bufferevent*>::iterator iVector;

        //        iVector = std::find(users.begin(),users.end(),bev);
        //        if(iVector!=users.end()){
        //            users.erase(iVector);
        //            printf("find user erase.\n");
        //        }
        //        else{
        //            printf("not find user erase.\n");
        //        }

        struct client *buf = (struct client *)user_data;

        std::map<bufferevent*, std::string>::iterator it = users.end();
        it = std::find_if(users.begin(), users.end(), map_value_finder(buf->mail));
        if (it == users.end()){
            printf("not found:%s\n",buf->mail);
        }else{
//            char user_mail[30];
//            memset(user_mail,0,sizeof(user_mail));
            //            strcpy_s(user_mail, iter->second.c_str());
            //            strncpy(&msg[6],&rev_data[6],len_r-6);
//            sprintf(user_mail,"%s",it->second.c_str());
            printf("find %s user erase.\n",buf->mail);
            users.erase(it);
            allusers[buf->mail]=false;
            map<bufferevent*, string >::iterator map_iter = users.begin();
            for(;map_iter!=users.end();map_iter++){
                printf("left list:%s\n",map_iter->second.c_str());
                socksend(map_iter->first,buf->mail,1002);
                //                            bufferevent_write(map_iter->first, msg, strlen(msg));
            }
        }

//        map<bufferevent*, string >::iterator iter;
//        iter = users.find(bev);
//        if(iter==users.end()){
//            printf("not find user erase.\n");
//        }
//        else{
//            char user_mail[30];
//            memset(user_mail,0,sizeof(user_mail));
//            //            strcpy_s(user_mail, iter->second.c_str());
//            //            strncpy(&msg[6],&rev_data[6],len_r-6);
//            sprintf(user_mail,"%s",iter->second.c_str());
//            printf("find %s user erase.\n",user_mail);
//            users.erase(iter);
//            allusers[user_mail]=false;
//            map<bufferevent*, string >::iterator map_iter = users.begin();
//            for(;map_iter!=users.end();map_iter++){
//                socksend(map_iter->first,user_mail,1002);
//            }
//        }

        evbuffer_free(buf->buf);

        bufferevent_free(buf->buf_ev);
        close(buf->fd);
        free(buf);
    }

    static void signal_cb(evutil_socket_t sig, short events, void *user_data){
        struct event_base *base = (event_base *)user_data;
        struct timeval delay = { 2, 0 };

        printf("Caught an interrupt signal; exiting cleanly in two seconds.\n");

        event_base_loopexit(base, &delay);
    }

    int start(int argc, char **argv){
        struct event_base *base;
        struct evconnlistener *listener;
        struct event *signal_event;

        struct sockaddr_in sin;
        //int server_socketfd;

#ifdef _WIN32
        WSADATA wsa_data;
        WSAStartup(0x0201, &wsa_data);
#endif
        memset(piIp,0,sizeof(piIp));
        char buffer[50]={0};
        char pathbuf[128]={0};
        char mp[] = "PORT";
        int port = 0;
        if(getcwd(pathbuf,sizeof(pathbuf))!=NULL){
            strcat(pathbuf,"/config/user.ini");
            read_file(pathbuf,mp,buffer);
            for(int i=0;i<(int)strlen(buffer)-1;i++){
                port += (buffer[i]-'0')*mpow(10,strlen(buffer)-i-2);
            }
            PORT = port;
        }

        memset(&sin, 0, sizeof(sin));
        sin.sin_family = AF_INET;//设置为IP通信
        sin.sin_addr.s_addr = INADDR_ANY;//服务器IP地址--允许连接到所有本地地址上
        sin.sin_port = htons(PORT);

        //        server_socketfd = socket(PF_INET,SOCK_STREAM,0);

        //        if(server_socketfd<0){
        //            fprintf(stderr, "socket error!\n");
        //            return 0;
        //        }

        //        evutil_make_listen_socket_reuseable(server_socketfd);//设置端口重用
        //        evutil_make_socket_nonblocking(server_socketfd);//设置无阻塞

        base = event_base_new();
        if (!base) {
            fprintf(stderr, "Could not initialize libevent!\n");
            return 1;
        }

        const char *x = event_base_get_method(base);//获取IO多路复用的模型
        printf("Method:%s\n",x);

        listener = evconnlistener_new_bind(base, listener_cb, (void *)base,
                                           LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_FREE, -1,
                                           (struct sockaddr*)&sin,
                                           sizeof(sin));

        if (!listener) {
            fprintf(stderr, "Could not create a listener!\n");
            return 1;
        }

        signal_event = evsignal_new(base, SIGINT, signal_cb, (void *)base);

        if (!signal_event || event_add(signal_event, NULL)<0) {
            fprintf(stderr, "Could not create/add a signal event!\n");
            return 1;
        }

        printf("Set Service success.Port:%d\n",PORT);

        event_base_dispatch(base);

        evconnlistener_free(listener);
        event_free(signal_event);
        event_base_free(base);

        printf("done\n");
        return 0;
    }

    static void socksend(struct bufferevent *bev,const char *pbuf,int type){
        char sendbuf[READBUFFER_MAX]={0};
        sprintf(sendbuf,"@@%04d%04d%s\n",(int)strlen(pbuf)+10,type,pbuf);
        //printf("%s\n",sendbuf);
        bufferevent_write(bev, sendbuf, strlen(sendbuf));
    }

private:
    int mpow(int e,int n){
        int r=e;
        if(n==0)
            return 1;

        while (--n) {
            r*=e;
        }

        return r;
    }

    int PORT;
};




int main(int argc, char **argv)
{
    Server *ser = new Server();
    return ser->start(argc,argv);
}


